import React, { Component } from 'react'
import Popper from 'popper.js'
import './select.scss'
import PropTypes from 'prop-types';
import requestAnimationFrame from 'raf';

class Select extends Component {
  constructor(props) {
    super(props)
    this.state = {
      showPopper: false,
      value: '',
      classname: ''
    }
    this.popperWrapRef = React.createRef()
    this.popperCtnRef = React.createRef()
    this.createPopper = this.createPopper.bind(this)
    this.inputOnFocus = this.inputOnFocus.bind(this)
    this.inputOnClick = this.inputOnClick.bind(this)
    this.inputOnChange = this.inputOnChange.bind(this)
    this.didEnter = this.didEnter.bind(this)
    this.didLeave = this.didLeave.bind(this)
    this.beforeEnter = this.beforeEnter.bind(this)
    this.beforeLeave = this.beforeLeave.bind(this)
    this.clickEventHandle = this.clickEventHandle.bind(this)
  }
  hasClass (el, className) {
    return el.classList ? el.classList.contains(className) : new RegExp('\\b' + className + '\\b').test(el.className)
  }
  addClass (el, className) {
    if (el.classList) el.classList.add(className)
    else if (!this.hasClass(el, className)) el.className += ' ' + className
  }
  removeClass (el, className) {
    if (el.classList) el.classList.remove(className)
    else el.className = el.className.replace(new RegExp('\\b' + className + '\\b', 'g'), '')
  }
  inputOnFocus (e) {
    this.setState({
      showPopper: true
    })
  }
  inputOnChange (e) {
  }
  inputOnClick (e) {
    e.nativeEvent.stopImmediatePropagation();
  }
  createPopper () {
    this.popper = new Popper(this.popperWrapRef.current, this.popperCtnRef.current, {
      modifiers: {
        computeStyle: {
          gpuAcceleration: false // If true, it uses the CSS 3D transformation to position the popper. Otherwise, it will use the top and left properties
        },
        offset: {
          fn: data => {
            return data
          }
        },
        preset: {
          enabled: true,
          fn: data => {
            return data
          }
        }
      }
    })
  }
  clickEventHandle () {
    if (this.state.showPopper) {
      this.setState({
        showPopper: false
      })
    }
  }
  setValue (item) {
    this.setState({
      value: item.label
    })
    this.props.onChange(item.value)
  }
  updatePopper () {
    this.popper ? this.popper.update() : this.createPopper()
  }
  componentWillUpdate (nextState, nextProps) { // 2
  }
  beforeEnter () {
    this.popperCtnRef.current.removeEventListener('transitionend', this.didLeave)
    this.removeClass(this.popperCtnRef.current, 'tbc-transition-leave-start')
    this.removeClass(this.popperCtnRef.current, 'tbc-transition-leave-active')
    this.removeClass(this.popperCtnRef.current, 'tbc-transition-leave-end')
  }
  beforeLeave () {
    this.popperCtnRef.current.removeEventListener('transitionend', this.didEnter)
    this.removeClass(this.popperCtnRef.current, 'tbc-transition-enter-start')
    this.removeClass(this.popperCtnRef.current, 'tbc-transition-enter-active')
    this.removeClass(this.popperCtnRef.current, 'tbc-transition-enter-end')
  }
  didEnter () {
    this.removeClass(this.popperCtnRef.current, 'tbc-transition-enter-start')
    this.removeClass(this.popperCtnRef.current, 'tbc-transition-enter-active')
    this.removeClass(this.popperCtnRef.current, 'tbc-transition-enter-end')
  }
  didLeave () {
    this.popperCtnRef.current.style.display = 'none'
    this.removeClass(this.popperCtnRef.current, 'tbc-transition-leave-start')
    this.removeClass(this.popperCtnRef.current, 'tbc-transition-leave-active')
    this.removeClass(this.popperCtnRef.current, 'tbc-transition-leave-end')
  }
  componentWillReceiveProps () { // ones ,1
  }
  componentDidUpdate (nextState, preProps) { // 3
    if (this.state.showPopper !== preProps.showPopper) {
      if (!preProps.showPopper) { // 只需要watch,showPopper,现在value改变也会新建
        this.beforeEnter()
        this.popperCtnRef.current.addEventListener('transitionend', this.didEnter)
        this.addClass(this.popperCtnRef.current, 'tbc-transition-enter-start')
        this.addClass(this.popperCtnRef.current, 'tbc-transition-enter-active')
        requestAnimationFrame(() => {
          this.addClass(this.popperCtnRef.current, 'tbc-transition-enter-end')
          requestAnimationFrame(() => {
          })
        })
        this.popperCtnRef.current.style.display = 'block'
        this.updatePopper()
      }
      if (preProps.showPopper) {
        this.beforeLeave()
        this.popperCtnRef.current.addEventListener('transitionend', this.didLeave)
        this.addClass(this.popperCtnRef.current, 'tbc-transition-leave-start')
        this.addClass(this.popperCtnRef.current, 'tbc-transition-leave-active')
        requestAnimationFrame(() => {
          this.addClass(this.popperCtnRef.current, 'tbc-transition-leave-end')
          requestAnimationFrame(() => {
          })
        })
      }
    }
  }
  componentDidMount () {
    document.addEventListener('click', this.clickEventHandle)
  }
  componentWillUnmount () {
    this.popper && this.popper.destroy()
    document.removeEventListener('click', this.clickEventHandle)
  }
  render () {
    return (
      <div ref={this.popperWrapRef} className="tbc-popper-wrap">
        <input value={this.state.value} onChange={this.inputOnChange} onFocus={this.inputOnFocus} onClick={this.inputOnClick} type="text" />
        <div ref={this.popperCtnRef} className={'tbc-popper-ctn'} style={{ display: 'none' }}>
          {this.props.children}
        </div>
      </div>
    )
  }
  getChildContext () {
    return {
      component: this
    }
  }
}

Select.childContextTypes = { // 定义childContextTypes，getChildContext才能用
  component: PropTypes.any
}

Select.propTypes = {
  value: PropTypes.any,
  onChange: PropTypes.func
}

export default Select